package com.zyy.game.tianlong.serviceimpl;

import com.zyy.game.tianlong.config.GameConfig;
import com.zyy.game.tianlong.dao.PlayerMapper;
import com.zyy.game.tianlong.entity.GamePlayer;
import com.zyy.game.tianlong.entity.Player;
import com.zyy.game.tianlong.task.GameInitRun;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import java.time.*;
import java.util.Date;
import java.util.Objects;

/**
 * @author relufi
 * @date 2019/8/12 0012
 */
@Service
public class PlayerServiceImpl {
    @Resource
    private PlayerMapper playerMapper;
    private final GameConfig gameConfig;
    private final StringRedisTemplate stringRedisTemplate;

    public PlayerServiceImpl(GameConfig gameConfig, StringRedisTemplate stringRedisTemplate) {
        this.gameConfig = gameConfig;
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Cacheable(cacheNames = "existPlayer", key = "'playerName_' + #playerName")
    public Boolean existPlayerName(String playerName) {
        return playerMapper.existByUserName(playerName) != null;
    }

    @Cacheable(cacheNames = "existPlayer", key = "'phone_' + #phone")
    public Boolean existPhone(String phone) {
        return playerMapper.existByPhone(phone) != null;
    }

    @Cacheable(cacheNames = "player", key = "'openId_' + #openId")
    public Player getByOpenId(String openId) {
        Player player = playerMapper.selectByOpenId(openId);
        resolveSignCount(player);
        return player;
    }

    @Cacheable(cacheNames = "player", key = "'phone_' + #phone")
    public Player getByPhone(String phone) {
        Player player = playerMapper.selectByPhone(phone);
        resolveSignCount(player);
        return player;
    }

    /**
     * 新增 账号密码注册的用户
     *
     * @param passWord 密码
     * @param phone    手机号
     * @param playerName 用户名
     */
    @Caching(
            evict = {@CacheEvict(cacheNames = "existPlayer", key = "'playerName_' + #playerName"), @CacheEvict(cacheNames = "existPlayer", key = "'phone_' + #phone"), @CacheEvict(cacheNames = "player", key = "'phone_' + #phone")}
    )
    public void addPwdPlayer(String passWord, String phone, String playerName) {
        Player player = new Player();
        player.setPassword(md5(passWord));
        player.setPlayerName(playerName);
        player.setPhone(phone);
        player.setPhoto(gameConfig.getDefaultImage());
        playerMapper.insertSelective(player);
    }

    /**
     * 新增 微信注册的用户
     *
     * @param openId     微信openId
     * @param playerName   用户名
     * @param headImgUrl 头像
     */
    @Caching(evict = {@CacheEvict(cacheNames = "existPlayer", key = "'playerName_' + #result.playerName"), @CacheEvict(cacheNames = "player", key = "'openId_' + #openId")})
    public Player addWxPlayer(String openId, String playerName, String headImgUrl) {
        Player player = new Player();
        player.setOpenId(openId);
        player.setPlayerName(playerName);
        player.setPhoto(headImgUrl);
        player.setPhoto(gameConfig.getDefaultImage());
        playerMapper.insertSelective(player);
        resolveSignCount(player);
        return player;
    }

    private void resolveSignCount(Player player) {
        if (player != null && player.getSignCount() != 0 && player.getSignDate() != null) {
            if (player.getSignDate().toInstant().isBefore(LocalDateTime.of(LocalDate.now().minusDays(1), LocalTime.MIN).toInstant(ZoneOffset.ofHours(8)))) {
                player.setSignCount(0);
            }
        }
    }

    public String md5(String passWord) {
        return DigestUtils.md5DigestAsHex((passWord + "/" + gameConfig.getPassWordSlat()).getBytes());
    }

    /**
     * 修改密码
     *
     * @param phone    手机号
     * @param passWord 密码
     */
    @CacheEvict(cacheNames = "player", key = "'phone_' + #phone")
    public void resetPassWordByPhone(String phone, String passWord) {
        playerMapper.updatePassWordByPhone(phone, md5(passWord));
    }


    /**
     * 新增交易密码
     *
     * @param payPassWord 交易密码
     */
    @Caching(evict = {@CacheEvict(cacheNames = "player", key = "'openId_' + #gamePlayer.openId", condition = "#gamePlayer.openId != null"), @CacheEvict(cacheNames = "player", key = "'phone_' + #gamePlayer.phone", condition = "#gamePlayer.phone != null")})
    public int addPayPassWord(GamePlayer gamePlayer, String payPassWord) {
        return playerMapper.updatePayPassWordById(gamePlayer.getPlayerId(), md5(payPassWord));
    }

    /**
     * 签到  连续签到奖励
     * @param gamePlayer 玩家信息
     */
    @Caching(evict = {@CacheEvict(cacheNames = "player", key = "'openId_' + #gamePlayer.openId", condition = "#gamePlayer.openId != null"), @CacheEvict(cacheNames = "player", key = "'phone_' + #gamePlayer.phone", condition = "#gamePlayer.phone != null")})
    @Transactional(rollbackFor = Exception.class)
    public void signInReward(GamePlayer gamePlayer) {
        Player player = playerMapper.selectSignById(gamePlayer.getPlayerId());
        int signCount = player.getSignCount();
        Long bean = player.getBean();
        Date signDate = player.getSignDate();
        Player newPlayer = new Player();
        newPlayer.setPlayerId(gamePlayer.getPlayerId());
        newPlayer.setSignDate(new Date());
        if (signCount != 0 && signDate != null) {
            Instant instant = signDate.toInstant();
            LocalDate now = LocalDate.now();
            if (instant.isBefore(LocalDateTime.of(now.minusDays(1), LocalTime.MIN).toInstant(ZoneOffset.ofHours(8)))) {
                newPlayer.setSignCount(1);
                newPlayer.setBean(bean + Long.valueOf(Objects.requireNonNull(stringRedisTemplate.opsForList().index(GameInitRun.SIGN_IN_REWARD, 0), "签到奖励为空")));
                playerMapper.updateByPrimaryKeySelective(newPlayer);
            } else {
                int newSignCount = signCount + 1;
                if (newSignCount > 7) {
                    newSignCount = 1;
                }
                newPlayer.setSignCount(newSignCount);
                newPlayer.setBean(bean + Long.valueOf(Objects.requireNonNull(stringRedisTemplate.opsForList().index(GameInitRun.SIGN_IN_REWARD, newSignCount - 1), "签到奖励为空")));
                playerMapper.updateByPrimaryKeySelective(newPlayer);
            }
        } else {
            newPlayer.setSignCount(1);
            newPlayer.setBean(bean + Long.valueOf(Objects.requireNonNull(stringRedisTemplate.opsForList().index(GameInitRun.SIGN_IN_REWARD, 0), "签到奖励为空")));
            playerMapper.updateByPrimaryKeySelective(newPlayer);
        }
    }
    @Caching(evict = {@CacheEvict(cacheNames = "player", key = "'openId_' + #gamePlayer.openId", condition = "#gamePlayer.openId != null"), @CacheEvict(cacheNames = "player", key = "'phone_' + #gamePlayer.phone", condition = "#gamePlayer.phone != null")})
    public void changeInfo(Player player, GamePlayer gamePlayer) {
        player.setPlayerId(gamePlayer.getPlayerId());
        playerMapper.updateByPrimaryKeySelective(player);
    }
}
